package cn.ug.product.web.controller;

import cn.ug.aop.RequiresPermissions;
import cn.ug.bean.base.DataTable;
import cn.ug.bean.base.SerializeObject;
import cn.ug.bean.type.ResultType;
import cn.ug.core.SerializeObjectError;
import cn.ug.product.bean.*;
import cn.ug.product.bean.response.ProductFindBean;
import cn.ug.product.service.GoldPriceBaselineService;
import cn.ug.product.service.GoldPriceRecordService;
import cn.ug.product.service.ProductService;
import cn.ug.util.DateUtils;
import cn.ug.util.ExportExcelUtil;
import cn.ug.util.UF;
import cn.ug.web.controller.BaseController;
import cn.ug.web.controller.ExportExcelController;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import static java.math.BigDecimal.ROUND_HALF_UP;
import static org.springframework.web.bind.annotation.RequestMethod.GET;

/**
 * 价格
 * @author kaiwotech
 */
@RestController
@RequestMapping("price")
public class PriceController extends BaseController {

    @Resource
    private ProductService productService;
    @Resource
    private GoldPriceRecordService goldPriceRecordService;
    @Resource
    private GoldPriceBaselineService goldPriceBaselineService;

    @RequestMapping(value = "/everyday", method = GET)
    public SerializeObject<List<GoldLatestPriceBean>> listLatestPrice(String startDate, String endDate) {
        List<GoldLatestPriceBean> dataList = goldPriceRecordService.listLatestValue(startDate, endDate);
        return new SerializeObject<>(ResultType.NORMAL, dataList);
    }

    @RequestMapping(value = "/someday", method = GET)
    public SerializeObject<Double> getSomedayPrice(String someday) {
        double price = goldPriceRecordService.selectSomedayPrice(someday);
        return new SerializeObject<>(ResultType.NORMAL, price);
    }

    @RequestMapping(value = "/latest/three/record", method = GET)
    public SerializeObject<List<GoldPriceRecordBean>> latestThreeRecord() {
        List<GoldPriceRecordBean> dataList = goldPriceRecordService.queryLatestRecordThree();
        return new SerializeObject<>(ResultType.NORMAL, dataList);
    }

    /**
     * 当日价格走势
     * @return  记录集
     */
    @RequestMapping(value = "todayTrend", method = GET)
    public SerializeObject todayTrend() {
        List<GoldPriceTrendBean> dataList = goldPriceRecordService.queryToday(null);
        DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern("HHmm");
        Calendar cal = Calendar.getInstance();
        //cal.add(Calendar.DAY_OF_YEAR, -8);
        int value = 0;
        List<GoldPriceTrendBean> result = new ArrayList<GoldPriceTrendBean>();
        int week = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (week < 0) {
            week = 0;
        }
        int index = 0;
        switch (week) {
            case 0:
                //value = 48;
                value = 96;
                for (GoldPriceTrendBean bean : dataList) {
                    if (index % 3 == 0) {
                        result.add(bean);
                    }
                }
                break;
            case 1:
                //value = 123;
                value = 164;
                for (GoldPriceTrendBean bean : dataList) {
                    int point = Integer.parseInt(timeFormat.format(UF.getDateTime(bean.getAddTimeString())));
                    if ((point >= 0 && point <= 900)
                            || (point >= 1130 && point <= 1330)
                            || (point >= 1530 && point <= 2000)) {
                        if (index % 3 == 0) {
                            result.add(bean);
                        }
                    } else {
                        result.add(bean);
                    }
                    index++;
                }
                break;
            case 2:
            case 3:
            case 4:
            case 5:
                //value = 148;
                value = 184;
                for (GoldPriceTrendBean bean : dataList) {
                    int point = Integer.parseInt(timeFormat.format(UF.getDateTime(bean.getAddTimeString())));
                    if ((point >= 230 && point <= 900)
                            || (point >= 1130 && point <= 1330)
                            || (point >= 1530 && point <= 2000)) {
                        if (index % 3 == 0) {
                            result.add(bean);
                        }
                    } else {
                        result.add(bean);
                    }
                    index++;
                }
                break;
            case 6:
                //value = 73;
                value = 116;
                for (GoldPriceTrendBean bean : dataList) {
                    int point = Integer.parseInt(timeFormat.format(UF.getDateTime(bean.getAddTimeString())));
                    if (point >= 230 && point <= 2359) {
                        if (index % 3 == 0) {
                            result.add(bean);
                        }
                    } else {
                        result.add(bean);
                    }
                    index++;
                }
                break;
            default:
                break;
        }
        return new SerializeObject<>(ResultType.NORMAL, String.valueOf(value), result);
    }

    /**
     *
     * 最近价格走势
     * @param day   查询最近天数 7、30、365
     * @return      记录集
     */
    @RequestMapping(value = "recentTrend", method = GET)
    public SerializeObject recentTrend(Integer day) {
        if (day == null || (day != 7 && day != 30 && day != 365)) {
            return new SerializeObjectError("00000002");
        }
        LocalDateTime addTimeMax = UF.getDate(UF.getFormatDateNow());
        LocalDateTime addTimeMin = addTimeMax.minusDays(day);
        List<GoldPriceTrendBean> dataList = goldPriceRecordService.queryTrend(null, addTimeMin, addTimeMax,day);
        return new SerializeObject<>(ResultType.NORMAL, dataList);
    }

    /**
     * 当前价格
     * @return  记录集
     */
    @RequestMapping(value = "currentGoldPrice", method = GET)
    public SerializeObject currentGoldPrice() {
        GoldPriceRecordBean goldPriceRecordBean = goldPriceRecordService.findLastByTime();
        if(null == goldPriceRecordBean) {
            return new SerializeObjectError("00000003");
        }

        return new SerializeObject<>(ResultType.NORMAL, goldPriceRecordBean.getLatestpri());
    }

    /**
     * 收益计算
     * 收益计算公式=购买克重*投资期限*年化收益/100/365
     * @param productId 产品ID
     * @return  记录集
     */
    @RequestMapping(value = "income", method = GET)
    public SerializeObject income(String productId, BigDecimal weight) {
        if(StringUtils.isBlank(productId) || null == weight || (weight.compareTo(new BigDecimal("0"))) != 1) {
            return new SerializeObjectError("00000002");
        }
        ProductFindBean entity = productService.queryProductById(productId);
        if(null == entity || StringUtils.isBlank(entity.getId())) {
            return new SerializeObjectError("00000003");
        }

        // *投资期限
        BigDecimal income = weight.multiply(new BigDecimal(entity.getInvestDay()));
        // *年化收益/100/365
        income = income.multiply(entity.getYearsIncome());
        income = income.divide(new BigDecimal("100"), 10, ROUND_HALF_UP);
        income = income.divide(new BigDecimal("365"), 10, ROUND_HALF_UP);
        // +本金
        income = income.add(weight);
        String incomePrice = income.setScale(5, ROUND_HALF_UP).toString();

        return new SerializeObject<>(ResultType.NORMAL, incomePrice, incomePrice);
    }

    /**
     * 当前基准金价
     * @return  记录集
     */
    @RequiresPermissions("price:view:goldPriceBaseline")
    @GetMapping("currentGoldPriceBaseline")
    public SerializeObject<GoldPriceBaselineBean> currentGoldPriceBaseline() {
        GoldPriceBaselineBean goldPriceBaselineBean = goldPriceBaselineService.findLastByTime();
        if(null == goldPriceBaselineBean) {
            return new SerializeObjectError<>("00000003");
        }

        return new SerializeObject<>(ResultType.NORMAL, goldPriceBaselineBean);
    }

    /**
     * 更新当前基准金价
     * @param accessToken		登录成功后分配的Key
     * @param entity		    记录集
     * @return				    是否操作成功
     */
    @RequiresPermissions("price:update:goldPriceBaseline")
    @PostMapping("updateGoldPriceBaseline")
    public SerializeObject updateGoldPriceBaseline(@RequestHeader String accessToken, GoldPriceBaselineBean entity) {
        if(null == entity || null == entity.getGoldPrice() || null == entity.getLimit()) {
            return new SerializeObjectError("00000002");
        }
        goldPriceBaselineService.saveOrUpdate(entity);
        return new SerializeObject(ResultType.NORMAL, "00000001");
    }

    /**
     *
     * 查询金价数据列表
     * @return      记录集
     */
    @RequestMapping(value = "queryPriceList", method = GET)
    public SerializeObject queryPriceList(Integer pageSize,Integer pageNum,String startDate,String endDate) {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)){
                if (dateFormat.parse(endDate).getTime() < dateFormat.parse(startDate).getTime()){
                    return new SerializeObject<>(ResultType.ERROR,"15000201");
                }
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return new SerializeObject<>(ResultType.NORMAL, goldPriceRecordService.queryPriceList(pageSize,pageNum,startDate,endDate));
    }

    /**
     *
     * 查询金价数据列表
     * @return      记录集
     */
    @RequestMapping(value = "export", method = GET)
    public SerializeObject export(HttpServletResponse response,String startDate, String endDate) {
        String[] columnNames = {"序号", "日期", "前台展示金价（元/克）", "数据源金价（元/克）"};
        String[] columns = {"index", "addTimeString", "latestpri", "actualpri"};
        String fileName = "金价数据列表";

        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            if (StringUtils.isBlank(startDate) || StringUtils.isBlank(endDate)){
                return new SerializeObject<>(ResultType.ERROR,"15000204");
            }

            if (dateFormat.parse(endDate).getTime() < dateFormat.parse(startDate).getTime()){
                return new SerializeObject<>(ResultType.ERROR,"15000201");
            }

            if (DateUtils.differentDaysByMillisecond(dateFormat.parse(startDate),dateFormat.parse(endDate))>7){
                return new SerializeObject<>(ResultType.ERROR,"15000202");
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        ExportExcelController<GoldPriceRecordExportBean> export = new ExportExcelController<>();
        DataTable<GoldPriceRecordBean> dataTable = goldPriceRecordService.queryPriceList(0,1,startDate,endDate);
        if (CollectionUtils.isEmpty(dataTable.getDataList())){
            return new SerializeObject<>(ResultType.ERROR,"15000203");
        }
        export.exportExcel(fileName, fileName, columnNames, columns,wrapPutGoldBeanData(dataTable.getDataList()),
                response, ExportExcelUtil.EXCEL_FILE_2003);

        return new SerializeObject<>(ResultType.NORMAL);
    }

    private List<GoldPriceRecordExportBean> wrapPutGoldBeanData(List<GoldPriceRecordBean> list) {
        int index = 1;
        List<GoldPriceRecordExportBean> goldPriceRecordExportBeanList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)){
            for (GoldPriceRecordBean bean : list) {
                GoldPriceRecordExportBean goldPriceRecordExportBean = new GoldPriceRecordExportBean();
                BeanUtils.copyProperties(bean,goldPriceRecordExportBean);
                goldPriceRecordExportBean.setIndex(index++);
                goldPriceRecordExportBeanList.add(goldPriceRecordExportBean);
            }
        }
        return goldPriceRecordExportBeanList;
    }

}
